
<!DOCTYPE HTML>
<html lang="" >
    <head>
        <meta charset="UTF-8">
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>Reducing Boilerplate · GitBook</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="description" content="">
        <meta name="generator" content="GitBook 3.2.2">
        
        
        
    
    <link rel="stylesheet" href="../gitbook/style.css">

    
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-highlight/website.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-search/search.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css">
                
            
        

    

    
        
    
        
    
        
    
        
    
        
    
        
    

        
    
    
    <meta name="HandheldFriendly" content="true"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="../gitbook/images/apple-touch-icon-precomposed-152.png">
    <link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">

    
    <link rel="next" href="ServerRendering.html" />
    
    
    <link rel="prev" href="UsingObjectSpreadOperator.html" />
    

    </head>
    <body>
        
<div class="book">
    <div class="book-summary">
        
            
<div id="book-search-input" role="search">
    <input type="text" placeholder="Type to search" />
</div>

            
                <nav role="navigation">
                


<ul class="summary">
    
    

    

    
        
        
    
        <li class="chapter " data-level="1.1" data-path="../">
            
                <a href="../">
            
                    
                    Read Me
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2" data-path="../introduction/">
            
                <a href="../introduction/">
            
                    
                    Introduction
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.2.1" data-path="../introduction/Motivation.html">
            
                <a href="../introduction/Motivation.html">
            
                    
                    Motivation
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.2" data-path="../introduction/CoreConcepts.html">
            
                <a href="../introduction/CoreConcepts.html">
            
                    
                    Core Concepts
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.3" data-path="../introduction/ThreePrinciples.html">
            
                <a href="../introduction/ThreePrinciples.html">
            
                    
                    Three Principles
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.4" data-path="../introduction/PriorArt.html">
            
                <a href="../introduction/PriorArt.html">
            
                    
                    Prior Art
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.5" data-path="../introduction/Ecosystem.html">
            
                <a href="../introduction/Ecosystem.html">
            
                    
                    Ecosystem
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2.6" data-path="../introduction/Examples.html">
            
                <a href="../introduction/Examples.html">
            
                    
                    Examples
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.3" data-path="../basics/">
            
                <a href="../basics/">
            
                    
                    Basics
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.3.1" data-path="../basics/Actions.html">
            
                <a href="../basics/Actions.html">
            
                    
                    Actions
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.2" data-path="../basics/Reducers.html">
            
                <a href="../basics/Reducers.html">
            
                    
                    Reducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.3" data-path="../basics/Store.html">
            
                <a href="../basics/Store.html">
            
                    
                    Store
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.4" data-path="../basics/DataFlow.html">
            
                <a href="../basics/DataFlow.html">
            
                    
                    Data Flow
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.5" data-path="../basics/UsageWithReact.html">
            
                <a href="../basics/UsageWithReact.html">
            
                    
                    Usage with React
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.6" data-path="../basics/ExampleTodoList.html">
            
                <a href="../basics/ExampleTodoList.html">
            
                    
                    Example: Todo List
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4" data-path="../advanced/">
            
                <a href="../advanced/">
            
                    
                    Advanced
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.1" data-path="../advanced/AsyncActions.html">
            
                <a href="../advanced/AsyncActions.html">
            
                    
                    Async Actions
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.2" data-path="../advanced/AsyncFlow.html">
            
                <a href="../advanced/AsyncFlow.html">
            
                    
                    Async Flow
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.3" data-path="../advanced/Middleware.html">
            
                <a href="../advanced/Middleware.html">
            
                    
                    Middleware
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.4" data-path="../advanced/UsageWithReactRouter.html">
            
                <a href="../advanced/UsageWithReactRouter.html">
            
                    
                    Usage with React Router
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.5" data-path="../advanced/ExampleRedditAPI.html">
            
                <a href="../advanced/ExampleRedditAPI.html">
            
                    
                    Example: Reddit API
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.6" >
            
                <span>
            
                    
                    Next Steps
            
                </span>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5" data-path="./">
            
                <a href="./">
            
                    
                    Recipes
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.1" data-path="MigratingToRedux.html">
            
                <a href="MigratingToRedux.html">
            
                    
                    Migrating to Redux
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.2" data-path="UsingObjectSpreadOperator.html">
            
                <a href="UsingObjectSpreadOperator.html">
            
                    
                    Using Object Spread Operator
            
                </a>
            

            
        </li>
    
        <li class="chapter active" data-level="1.5.3" data-path="ReducingBoilerplate.html">
            
                <a href="ReducingBoilerplate.html">
            
                    
                    Reducing Boilerplate
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.4" data-path="ServerRendering.html">
            
                <a href="ServerRendering.html">
            
                    
                    Server Rendering
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.5" data-path="WritingTests.html">
            
                <a href="WritingTests.html">
            
                    
                    Writing Tests
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.6" data-path="ComputingDerivedData.html">
            
                <a href="ComputingDerivedData.html">
            
                    
                    Computing Derived Data
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.7" data-path="ImplementingUndoHistory.html">
            
                <a href="ImplementingUndoHistory.html">
            
                    
                    Implementing Undo History
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8" data-path="IsolatingSubapps.html">
            
                <a href="IsolatingSubapps.html">
            
                    
                    Isolating Subapps
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9" data-path="StructuringReducers.html">
            
                <a href="StructuringReducers.html">
            
                    
                    Structuring Reducers
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.9.1" data-path="reducers/PrerequisiteConcepts.html">
            
                <a href="reducers/PrerequisiteConcepts.html">
            
                    
                    Prerequisite Concepts
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.2" data-path="reducers/BasicReducerStructure.html">
            
                <a href="reducers/BasicReducerStructure.html">
            
                    
                    Basic Reducer Structure
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.3" data-path="reducers/SplittingReducerLogic.html">
            
                <a href="reducers/SplittingReducerLogic.html">
            
                    
                    Splitting Reducer Logic
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.4" data-path="reducers/RefactoringReducersExample.html">
            
                <a href="reducers/RefactoringReducersExample.html">
            
                    
                    Refactoring Reducers Example
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.5" data-path="reducers/UsingCombineReducers.html">
            
                <a href="reducers/UsingCombineReducers.html">
            
                    
                    Using combineReducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.6" data-path="reducers/BeyondCombineReducers.html">
            
                <a href="reducers/BeyondCombineReducers.html">
            
                    
                    Beyond combineReducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.7" data-path="reducers/NormalizingStateShape.html">
            
                <a href="reducers/NormalizingStateShape.html">
            
                    
                    Normalizing State Shape
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.8" data-path="reducers/UpdatingNormalizedData.html">
            
                <a href="reducers/UpdatingNormalizedData.html">
            
                    
                    Updating Normalized Data
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.9" data-path="reducers/ReusingReducerLogic.html">
            
                <a href="reducers/ReusingReducerLogic.html">
            
                    
                    Reusing Reducer Logic
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.10" data-path="reducers/ImmutableUpdatePatterns.html">
            
                <a href="reducers/ImmutableUpdatePatterns.html">
            
                    
                    Immutable Update Patterns
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.9.11" data-path="reducers/InitializingState.html">
            
                <a href="reducers/InitializingState.html">
            
                    
                    Initializing State
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.10" data-path="UsingImmutableJS.html">
            
                <a href="UsingImmutableJS.html">
            
                    
                    Using Immutable.JS with Redux
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6" data-path="../FAQ.html">
            
                <a href="../FAQ.html">
            
                    
                    FAQ
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.1" data-path="../faq/General.html">
            
                <a href="../faq/General.html">
            
                    
                    General
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2" data-path="../faq/Reducers.html">
            
                <a href="../faq/Reducers.html">
            
                    
                    Reducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.3" data-path="../faq/OrganizingState.html">
            
                <a href="../faq/OrganizingState.html">
            
                    
                    Organizing State
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.4" data-path="../faq/StoreSetup.html">
            
                <a href="../faq/StoreSetup.html">
            
                    
                    Store Setup
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.5" data-path="../faq/Actions.html">
            
                <a href="../faq/Actions.html">
            
                    
                    Actions
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6" data-path="../faq/ImmutableData.html">
            
                <a href="../faq/ImmutableData.html">
            
                    
                    Immutable Data
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.7" data-path="../faq/CodeStructure.html">
            
                <a href="../faq/CodeStructure.html">
            
                    
                    Code Structure
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8" data-path="../faq/Performance.html">
            
                <a href="../faq/Performance.html">
            
                    
                    Performance
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9" data-path="../faq/ReactRedux.html">
            
                <a href="../faq/ReactRedux.html">
            
                    
                    React Redux
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10" data-path="../faq/Miscellaneous.html">
            
                <a href="../faq/Miscellaneous.html">
            
                    
                    Miscellaneous
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7" data-path="../Troubleshooting.html">
            
                <a href="../Troubleshooting.html">
            
                    
                    Troubleshooting
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.8" data-path="../Glossary.html">
            
                <a href="../Glossary.html">
            
                    
                    Glossary
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9" data-path="../api/">
            
                <a href="../api/">
            
                    
                    API Reference
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.9.1" data-path="../api/createStore.html">
            
                <a href="../api/createStore.html">
            
                    
                    createStore
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.2" data-path="../api/Store.html">
            
                <a href="../api/Store.html">
            
                    
                    Store
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.3" data-path="../api/combineReducers.html">
            
                <a href="../api/combineReducers.html">
            
                    
                    combineReducers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.4" data-path="../api/applyMiddleware.html">
            
                <a href="../api/applyMiddleware.html">
            
                    
                    applyMiddleware
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.5" data-path="../api/bindActionCreators.html">
            
                <a href="../api/bindActionCreators.html">
            
                    
                    bindActionCreators
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.6" data-path="../api/compose.html">
            
                <a href="../api/compose.html">
            
                    
                    compose
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.10" data-path="../CHANGELOG.md">
            
                <span>
            
                    
                    Change Log
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.11" data-path="../PATRONS.md">
            
                <span>
            
                    
                    Patrons
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.12" data-path="../Feedback.html">
            
                <a href="../Feedback.html">
            
                    
                    Feedback
            
                </a>
            

            
        </li>
    

    

    <li class="divider"></li>

    <li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            Published with GitBook
        </a>
    </li>
</ul>


                </nav>
            
        
    </div>

    <div class="book-body">
        
            <div class="body-inner">
                
                    

<div class="book-header" role="navigation">
    

    <!-- Title -->
    <h1>
        <i class="fa fa-circle-o-notch fa-spin"></i>
        <a href=".." >Reducing Boilerplate</a>
    </h1>
</div>




                    <div class="page-wrapper" tabindex="-1" role="main">
                        <div class="page-inner">
                            
<div id="book-search-results">
    <div class="search-noresults">
    
                                <section class="normal markdown-section">
                                
                                <h1 id="reducing-boilerplate">Reducing Boilerplate</h1>
<p>Redux is in part <a href="../introduction/PriorArt.html">inspired by Flux</a>, and the most common complaint about Flux is how it makes you write a lot of boilerplate. In this recipe, we will consider how Redux lets us choose how verbose we&apos;d like our code to be, depending on personal style, team preferences, longer term maintainability, and so on.</p>
<h2 id="actions">Actions</h2>
<p>Actions are plain objects describing what happened in the app, and serve as the sole way to describe an intention to mutate the data. It&apos;s important that <strong>actions being objects you have to dispatch is not boilerplate, but one of the <a href="../introduction/ThreePrinciples.html">fundamental design choices</a> of Redux</strong>.</p>
<p>There are frameworks claiming to be similar to Flux, but without a concept of <a href="../Glossary.html#action" class="glossary-term" title="">action</a> objects. In terms of being predictable, this is a step backwards from Flux or Redux. If there are no serializable plain object actions, it is impossible to record and replay user sessions, or to implement <a href="https://www.youtube.com/watch?v=xsSnOQynTHs" target="_blank">hot reloading with time travel</a>. If you&apos;d rather modify data directly, you don&apos;t need Redux.</p>
<p>Actions look like this:</p>
<pre><code class="lang-js">{ type: <span class="hljs-string">&apos;ADD_TODO&apos;</span>, text: <span class="hljs-string">&apos;Use Redux&apos;</span> }
{ type: <span class="hljs-string">&apos;REMOVE_TODO&apos;</span>, id: <span class="hljs-number">42</span> }
{ type: <span class="hljs-string">&apos;LOAD_ARTICLE&apos;</span>, response: { ... } }
</code></pre>
<p>It is a common convention that actions have a constant type that helps reducers (or Stores in Flux) identify them. We recommend that you use strings and not <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Symbol" target="_blank">Symbols</a> for <a href="../Glossary.html#action" class="glossary-term" title="">action</a> types, because strings are serializable, and by using Symbols you make recording and replaying harder than it needs to be.</p>
<p>In Flux, it is traditionally thought that you would define every <a href="../Glossary.html#action" class="glossary-term" title="">action</a> type as a string constant:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> ADD_TODO = <span class="hljs-string">&apos;ADD_TODO&apos;</span>
<span class="hljs-keyword">const</span> REMOVE_TODO = <span class="hljs-string">&apos;REMOVE_TODO&apos;</span>
<span class="hljs-keyword">const</span> LOAD_ARTICLE = <span class="hljs-string">&apos;LOAD_ARTICLE&apos;</span>
</code></pre>
<p>Why is this beneficial? <strong>It is often claimed that constants are unnecessary, and for small projects, this might be correct.</strong> For larger projects, there are some benefits to defining <a href="../Glossary.html#action" class="glossary-term" title="">action</a> types as constants:</p>
<ul>
<li>It helps keep the naming consistent because all <a href="../Glossary.html#action" class="glossary-term" title="">action</a> types are gathered in a single place.</li>
<li>Sometimes you want to see all existing actions before working on a new feature. It may be that the <a href="../Glossary.html#action" class="glossary-term" title="">action</a> you need was already added by somebody on the team, but you didn&apos;t know.</li>
<li>The list of <a href="../Glossary.html#action" class="glossary-term" title="">action</a> types that were added, removed, and changed in a Pull Request helps everyone on the team keep track of scope and implementation of new features.</li>
<li>If you make a typo when importing an <a href="../Glossary.html#action" class="glossary-term" title="">action</a> constant, you will get <code>undefined</code>. Redux will immediately throw when dispatching such an <a href="../Glossary.html#action" class="glossary-term" title="">action</a>, and you&apos;ll find the mistake sooner.</li>
</ul>
<p>It is up to you to choose the conventions for your project. You may start by using inline strings, and later transition to constants, and maybe later group them into a single file. Redux does not have any opinion here, so use your best judgment.</p>
<h2 id="action-creators">Action Creators</h2>
<p>It is another common convention that, instead of creating <a href="../Glossary.html#action" class="glossary-term" title="">action</a> objects inline in the places where you dispatch the actions, you would create functions generating them.</p>
<p>For example, instead of calling <code>dispatch</code> with an object literal:</p>
<pre><code class="lang-js"><span class="hljs-comment">// somewhere in an event handler</span>
dispatch({
  type: <span class="hljs-string">&apos;ADD_TODO&apos;</span>,
  text: <span class="hljs-string">&apos;Use Redux&apos;</span>
})
</code></pre>
<p>You might write an <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creator in a separate file, and import it from your component:</p>
<h4 id="actioncreatorsjs"><code>actionCreators.js</code></h4>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addTodo</span>(<span class="hljs-params">text</span>) </span>{
  <span class="hljs-keyword">return</span> {
    type: <span class="hljs-string">&apos;ADD_TODO&apos;</span>,
    text
  }
}
</code></pre>
<h4 id="addtodojs"><code>AddTodo.js</code></h4>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { addTodo } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./actionCreators&apos;</span>

<span class="hljs-comment">// somewhere in an event handler</span>
dispatch(addTodo(<span class="hljs-string">&apos;Use Redux&apos;</span>))
</code></pre>
<p><a href="../Glossary.html#action" class="glossary-term" title="">Action</a> creators have often been criticized as boilerplate. Well, you don&apos;t have to write them! <strong>You can use object literals if you feel this better suits your project.</strong> There are, however, some benefits for writing <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creators you should know about.</p>
<p>Let&apos;s say a designer comes back to us after reviewing our prototype, and tells us that we need to allow three todos maximum. We can enforce this by rewriting our <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creator to a callback form with <a href="https://github.com/gaearon/redux-thunk" target="_blank">redux-thunk</a> <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> and adding an early exit:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addTodoWithoutCheck</span>(<span class="hljs-params">text</span>) </span>{
  <span class="hljs-keyword">return</span> {
    type: <span class="hljs-string">&apos;ADD_TODO&apos;</span>,
    text
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addTodo</span>(<span class="hljs-params">text</span>) </span>{
  <span class="hljs-comment">// This form is allowed by Redux Thunk middleware</span>
  <span class="hljs-comment">// described below in &#x201C;Async Action Creators&#x201D; section.</span>
  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">dispatch, getState</span>) </span>{
    <span class="hljs-keyword">if</span> (getState().todos.length === <span class="hljs-number">3</span>) {
      <span class="hljs-comment">// Exit early</span>
      <span class="hljs-keyword">return</span>
    }

    dispatch(addTodoWithoutCheck(text))
  }
}
</code></pre>
<p>We just modified how the <code>addTodo</code> <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creator behaves, completely invisible to the calling code. <strong>We don&apos;t have to worry about looking at each place where todos are being added, to make sure they have this check.</strong> <a href="../Glossary.html#action" class="glossary-term" title="">Action</a> creators let you decouple additional logic around dispatching an <a href="../Glossary.html#action" class="glossary-term" title="">action</a>, from the actual components emitting those actions. It&apos;s very handy when the application is under heavy development, and the requirements change often.</p>
<h3 id="generating-action-creators">Generating Action Creators</h3>
<p>Some frameworks like <a href="https://github.com/acdlite/flummox" target="_blank">Flummox</a> generate <a href="../Glossary.html#action" class="glossary-term" title="">action</a> type constants automatically from the <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creator function definitions. The idea is that you don&apos;t need to both define <code>ADD_TODO</code> constant and <code>addTodo()</code> <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creator. Under the hood, such solutions still generate <a href="../Glossary.html#action" class="glossary-term" title="">action</a> type constants, but they&apos;re created implicitly so it&apos;s a level of indirection and can cause confusion. We recommend creating your <a href="../Glossary.html#action" class="glossary-term" title="">action</a> type constants explicitly.</p>
<p>Writing simple <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creators can be tiresome and often ends up generating redundant boilerplate code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addTodo</span>(<span class="hljs-params">text</span>) </span>{
  <span class="hljs-keyword">return</span> {
    type: <span class="hljs-string">&apos;ADD_TODO&apos;</span>,
    text
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">editTodo</span>(<span class="hljs-params">id, text</span>) </span>{
  <span class="hljs-keyword">return</span> {
    type: <span class="hljs-string">&apos;EDIT_TODO&apos;</span>,
    id,
    text
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">removeTodo</span>(<span class="hljs-params">id</span>) </span>{
  <span class="hljs-keyword">return</span> {
    type: <span class="hljs-string">&apos;REMOVE_TODO&apos;</span>,
    id
  }
}
</code></pre>
<p>You can always write a function that generates an <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creator:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">makeActionCreator</span>(<span class="hljs-params">type, ...argNames</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">...args</span>) </span>{
    <span class="hljs-keyword">let</span> action = { type }
    argNames.forEach((arg, index) =&gt; {
      action[argNames[index]] = args[index]
    })
    <span class="hljs-keyword">return</span> action
  }
}

<span class="hljs-keyword">const</span> ADD_TODO = <span class="hljs-string">&apos;ADD_TODO&apos;</span>
<span class="hljs-keyword">const</span> EDIT_TODO = <span class="hljs-string">&apos;EDIT_TODO&apos;</span>
<span class="hljs-keyword">const</span> REMOVE_TODO = <span class="hljs-string">&apos;REMOVE_TODO&apos;</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> addTodo = makeActionCreator(ADD_TODO, <span class="hljs-string">&apos;todo&apos;</span>)
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> editTodo = makeActionCreator(EDIT_TODO, <span class="hljs-string">&apos;id&apos;</span>, <span class="hljs-string">&apos;todo&apos;</span>)
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> removeTodo = makeActionCreator(REMOVE_TODO, <span class="hljs-string">&apos;id&apos;</span>)
</code></pre>
<p>There are also utility libraries to aid in generating <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creators, such as <a href="https://github.com/pauldijou/redux-act" target="_blank">redux-act</a> and <a href="https://github.com/acdlite/redux-actions" target="_blank">redux-actions</a>. These can help reduce boilerplate code and enforce adherence to standards such as <a href="https://github.com/acdlite/flux-standard-action" target="_blank">Flux Standard Action (FSA)</a>.</p>
<h2 id="async-action-creators">Async Action Creators</h2>
<p><a href="../Glossary.html#middleware">Middleware</a> lets you inject custom logic that interprets every <a href="../Glossary.html#action" class="glossary-term" title="">action</a> object before it is dispatched. Async actions are the most common use case for <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>.</p>
<p>Without any <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>, <a href="../api/Store.html#dispatch"><code>dispatch</code></a> only accepts a plain object, so we have to perform AJAX calls inside our components:</p>
<h4 id="actioncreatorsjs"><code>actionCreators.js</code></h4>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadPostsSuccess</span>(<span class="hljs-params">userId, response</span>) </span>{
  <span class="hljs-keyword">return</span> {
    type: <span class="hljs-string">&apos;LOAD_POSTS_SUCCESS&apos;</span>,
    userId,
    response
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadPostsFailure</span>(<span class="hljs-params">userId, error</span>) </span>{
  <span class="hljs-keyword">return</span> {
    type: <span class="hljs-string">&apos;LOAD_POSTS_FAILURE&apos;</span>,
    userId,
    error
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadPostsRequest</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-keyword">return</span> {
    type: <span class="hljs-string">&apos;LOAD_POSTS_REQUEST&apos;</span>,
    userId
  }
}
</code></pre>
<h4 id="userinfojs"><code>UserInfo.js</code></h4>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>
<span class="hljs-keyword">import</span> { connect } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-redux&apos;</span>
<span class="hljs-keyword">import</span> { loadPostsRequest, loadPostsSuccess, loadPostsFailure } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./actionCreators&apos;</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Posts</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{
  loadData(userId) {
    <span class="hljs-comment">// Injected into props by React Redux `connect()` call:</span>
    <span class="hljs-keyword">let</span> { dispatch, posts } = <span class="hljs-keyword">this</span>.props

    <span class="hljs-keyword">if</span> (posts[userId]) {
      <span class="hljs-comment">// There is cached data! Don&apos;t do anything.</span>
      <span class="hljs-keyword">return</span>
    }

    <span class="hljs-comment">// Reducer can react to this action by setting</span>
    <span class="hljs-comment">// `isFetching` and thus letting us show a spinner.</span>
    dispatch(loadPostsRequest(userId))

    <span class="hljs-comment">// Reducer can react to these actions by filling the `users`.</span>
    fetch(<span class="hljs-string">`http://myapi.com/users/<span class="hljs-subst">${userId}</span>/posts`</span>).then(
      response =&gt; dispatch(loadPostsSuccess(userId, response)),
      error =&gt; dispatch(loadPostsFailure(userId, error))
    )
  }

  componentDidMount() {
    <span class="hljs-keyword">this</span>.loadData(<span class="hljs-keyword">this</span>.props.userId)
  }

  componentWillReceiveProps(nextProps) {
    <span class="hljs-keyword">if</span> (nextProps.userId !== <span class="hljs-keyword">this</span>.props.userId) {
      <span class="hljs-keyword">this</span>.loadData(nextProps.userId)
    }
  }

  render() {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.props.isFetching) {
      <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
    }

    <span class="hljs-keyword">let</span> posts = <span class="hljs-keyword">this</span>.props.posts.map(post =&gt;
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> /&gt;</span>
    )

    return <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{posts}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  }
}

export default connect(state =&gt; ({
  posts: state.posts
}))(Posts)
</span></code></pre>
<p>However, this quickly gets repetitive because different components request data from the same API endpoints. Moreover, we want to reuse some of this logic (e.g., early exit when there is cached data available) from many components.</p>
<p><strong><a href="../Glossary.html#middleware" class="glossary-term" title="">Middleware</a> lets us write more expressive, potentially async <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creators.</strong> It lets us dispatch something other than plain objects, and interprets the values. For example, <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> can &#x201C;catch&#x201D; dispatched Promises and turn them into a pair of request and success/failure actions.</p>
<p>The simplest example of <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> is <a href="https://github.com/gaearon/redux-thunk" target="_blank">redux-thunk</a>. <strong>&#x201C;Thunk&#x201D; <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> lets you write <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creators as &#x201C;thunks&#x201D;, that is, functions returning functions.</strong> This inverts the control: you will get <code>dispatch</code> as an argument, so you can write an <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creator that dispatches many times.</p>
<blockquote>
<h5 id="note">Note</h5>
<p>Thunk <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> is just one example of <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>. <a href="../Glossary.html#middleware" class="glossary-term" title="">Middleware</a> is not about &#x201C;letting you dispatch functions&#x201D;. It&apos;s about letting you dispatch anything that the particular <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> you use knows how to handle. Thunk <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> adds a specific behavior when you dispatch functions, but it really depends on the <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> you use.</p>
</blockquote>
<p>Consider the code above rewritten with <a href="https://github.com/gaearon/redux-thunk" target="_blank">redux-thunk</a>:</p>
<h4 id="actioncreatorsjs"><code>actionCreators.js</code></h4>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadPosts</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-comment">// Interpreted by the thunk middleware:</span>
  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">dispatch, getState</span>) </span>{
    <span class="hljs-keyword">let</span> { posts } = getState()
    <span class="hljs-keyword">if</span> (posts[userId]) {
      <span class="hljs-comment">// There is cached data! Don&apos;t do anything.</span>
      <span class="hljs-keyword">return</span>
    }

    dispatch({
      type: <span class="hljs-string">&apos;LOAD_POSTS_REQUEST&apos;</span>,
      userId
    })

    <span class="hljs-comment">// Dispatch vanilla actions asynchronously</span>
    fetch(<span class="hljs-string">`http://myapi.com/users/<span class="hljs-subst">${userId}</span>/posts`</span>).then(
      response =&gt; dispatch({
        type: <span class="hljs-string">&apos;LOAD_POSTS_SUCCESS&apos;</span>,
        userId,
        response
      }),
      error =&gt; dispatch({
        type: <span class="hljs-string">&apos;LOAD_POSTS_FAILURE&apos;</span>,
        userId,
        error
      })
    )
  }
}
</code></pre>
<h4 id="userinfojs"><code>UserInfo.js</code></h4>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react&apos;</span>
<span class="hljs-keyword">import</span> { connect } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;react-redux&apos;</span>
<span class="hljs-keyword">import</span> { loadPosts } <span class="hljs-keyword">from</span> <span class="hljs-string">&apos;./actionCreators&apos;</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Posts</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{
  componentDidMount() {
    <span class="hljs-keyword">this</span>.props.dispatch(loadPosts(<span class="hljs-keyword">this</span>.props.userId))
  }

  componentWillReceiveProps(nextProps) {
    <span class="hljs-keyword">if</span> (nextProps.userId !== <span class="hljs-keyword">this</span>.props.userId) {
      <span class="hljs-keyword">this</span>.props.dispatch(loadPosts(nextProps.userId))
    }
  }

  render() {
    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.props.isFetching) {
      <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
    }

    <span class="hljs-keyword">let</span> posts = <span class="hljs-keyword">this</span>.props.posts.map(post =&gt;
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> /&gt;</span>
    )

    return <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{posts}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  }
}

export default connect(state =&gt; ({
  posts: state.posts
}))(Posts)
</span></code></pre>
<p>This is much less typing! If you&apos;d like, you can still have &#x201C;vanilla&#x201D; <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creators like <code>loadPostsSuccess</code> which you&apos;d use from a container <code>loadPosts</code> <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creator.</p>
<p><strong>Finally, you can write your own <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a>.</strong> Let&apos;s say you want to generalize the pattern above and describe your async <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creators like this instead:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadPosts</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-keyword">return</span> {
    <span class="hljs-comment">// Types of actions to emit before and after</span>
    types: [<span class="hljs-string">&apos;LOAD_POSTS_REQUEST&apos;</span>, <span class="hljs-string">&apos;LOAD_POSTS_SUCCESS&apos;</span>, <span class="hljs-string">&apos;LOAD_POSTS_FAILURE&apos;</span>],
    <span class="hljs-comment">// Check the cache (optional):</span>
    shouldCallAPI: (state) =&gt; !state.posts[userId],
    <span class="hljs-comment">// Perform the fetching:</span>
    callAPI: () =&gt; fetch(<span class="hljs-string">`http://myapi.com/users/<span class="hljs-subst">${userId}</span>/posts`</span>),
    <span class="hljs-comment">// Arguments to inject in begin/end actions</span>
    payload: { userId }
  }
}
</code></pre>
<p>The <a href="../Glossary.html#middleware" class="glossary-term" title="">middleware</a> that interprets such actions could look like this:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">callAPIMiddleware</span>(<span class="hljs-params">{ dispatch, getState }</span>) </span>{
  <span class="hljs-keyword">return</span> next =&gt; action =&gt; {
    <span class="hljs-keyword">const</span> {
      types,
      callAPI,
      shouldCallAPI = () =&gt; <span class="hljs-literal">true</span>,
      payload = {}
    } = action

    <span class="hljs-keyword">if</span> (!types) {
      <span class="hljs-comment">// Normal action: pass it on</span>
      <span class="hljs-keyword">return</span> next(action)
    }

    <span class="hljs-keyword">if</span> (
      !<span class="hljs-built_in">Array</span>.isArray(types) ||
      types.length !== <span class="hljs-number">3</span> ||
      !types.every(type =&gt; <span class="hljs-keyword">typeof</span> type === <span class="hljs-string">&apos;string&apos;</span>)
    ) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">&apos;Expected an array of three string types.&apos;</span>)
    }

    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> callAPI !== <span class="hljs-string">&apos;function&apos;</span>) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">&apos;Expected callAPI to be a function.&apos;</span>)
    }

    <span class="hljs-keyword">if</span> (!shouldCallAPI(getState())) {
      <span class="hljs-keyword">return</span>
    }

    <span class="hljs-keyword">const</span> [ requestType, successType, failureType ] = types

    dispatch(<span class="hljs-built_in">Object</span>.assign({}, payload, {
      type: requestType
    }))

    <span class="hljs-keyword">return</span> callAPI().then(
      response =&gt; dispatch(<span class="hljs-built_in">Object</span>.assign({}, payload, {
        response,
        type: successType
      })),
      error =&gt; dispatch(<span class="hljs-built_in">Object</span>.assign({}, payload, {
        error,
        type: failureType
      }))
    )
  }
}
</code></pre>
<p>After passing it once to <a href="../api/applyMiddleware.html"><code>applyMiddleware(...middlewares)</code></a>, you can write all your API-calling <a href="../Glossary.html#action" class="glossary-term" title="">action</a> creators the same way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadPosts</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-keyword">return</span> {
    types: [<span class="hljs-string">&apos;LOAD_POSTS_REQUEST&apos;</span>, <span class="hljs-string">&apos;LOAD_POSTS_SUCCESS&apos;</span>, <span class="hljs-string">&apos;LOAD_POSTS_FAILURE&apos;</span>],
    shouldCallAPI: (state) =&gt; !state.posts[userId],
    callAPI: () =&gt; fetch(<span class="hljs-string">`http://myapi.com/users/<span class="hljs-subst">${userId}</span>/posts`</span>),
    payload: { userId }
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadComments</span>(<span class="hljs-params">postId</span>) </span>{
  <span class="hljs-keyword">return</span> {
    types: [<span class="hljs-string">&apos;LOAD_COMMENTS_REQUEST&apos;</span>, <span class="hljs-string">&apos;LOAD_COMMENTS_SUCCESS&apos;</span>, <span class="hljs-string">&apos;LOAD_COMMENTS_FAILURE&apos;</span>],
    shouldCallAPI: (state) =&gt; !state.comments[postId],
    callAPI: () =&gt; fetch(<span class="hljs-string">`http://myapi.com/posts/<span class="hljs-subst">${postId}</span>/comments`</span>),
    payload: { postId }
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">addComment</span>(<span class="hljs-params">postId, message</span>) </span>{
  <span class="hljs-keyword">return</span> {
    types: [<span class="hljs-string">&apos;ADD_COMMENT_REQUEST&apos;</span>, <span class="hljs-string">&apos;ADD_COMMENT_SUCCESS&apos;</span>, <span class="hljs-string">&apos;ADD_COMMENT_FAILURE&apos;</span>],
    callAPI: () =&gt; fetch(<span class="hljs-string">`http://myapi.com/posts/<span class="hljs-subst">${postId}</span>/comments`</span>, {
      method: <span class="hljs-string">&apos;post&apos;</span>,
      headers: {
        <span class="hljs-string">&apos;Accept&apos;</span>: <span class="hljs-string">&apos;application/json&apos;</span>,
        <span class="hljs-string">&apos;Content-Type&apos;</span>: <span class="hljs-string">&apos;application/json&apos;</span>
      },
      body: <span class="hljs-built_in">JSON</span>.stringify({ message })
    }),
    payload: { postId, message }
  }
}
</code></pre>
<h2 id="reducers">Reducers</h2>
<p>Redux reduces the boilerplate of Flux stores considerably by describing the update logic as a function. A function is simpler than an object, and much simpler than a class.</p>
<p>Consider this Flux <a href="../Glossary.html#store" class="glossary-term" title="">store</a>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> _todos = []

<span class="hljs-keyword">const</span> TodoStore = <span class="hljs-built_in">Object</span>.assign({}, EventEmitter.prototype, {
  getAll() {
    <span class="hljs-keyword">return</span> _todos
  }
})

AppDispatcher.register(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">action</span>) </span>{
  <span class="hljs-keyword">switch</span> (action.type) {
    <span class="hljs-keyword">case</span> ActionTypes.ADD_TODO:
      <span class="hljs-keyword">let</span> text = action.text.trim()
      _todos.push(text)
      TodoStore.emitChange()
  }
})

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> TodoStore
</code></pre>
<p>With Redux, the same update logic can be described as a reducing function:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">todos</span>(<span class="hljs-params">state = [], action</span>) </span>{
  <span class="hljs-keyword">switch</span> (action.type) {
  <span class="hljs-keyword">case</span> ActionTypes.ADD_TODO:
    <span class="hljs-keyword">let</span> text = action.text.trim()
    <span class="hljs-keyword">return</span> [ ...state, text ]
  <span class="hljs-keyword">default</span>:
    <span class="hljs-keyword">return</span> state
  }
}
</code></pre>
<p>The <code>switch</code> statement is <em>not</em> the real boilerplate. The real boilerplate of Flux is conceptual: the need to emit an update, the need to register the <a href="../Glossary.html#store" class="glossary-term" title="">Store</a> with a Dispatcher, the need for the <a href="../Glossary.html#store" class="glossary-term" title="">Store</a> to be an object (and the complications that arise when you want a universal app).</p>
<p>It&apos;s unfortunate that many still choose Flux framework based on whether it uses <code>switch</code> statements in the documentation. If you don&apos;t like <code>switch</code>, you can solve this with a single function, as we show below.</p>
<h3 id="generating-reducers">Generating Reducers</h3>
<p>Let&apos;s write a function that lets us express reducers as an object mapping from <a href="../Glossary.html#action" class="glossary-term" title="">action</a> types to handlers. For example, if we want our <code>todos</code> reducers to be defined like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> todos = createReducer([], {
  [ActionTypes.ADD_TODO](state, action) {
    <span class="hljs-keyword">let</span> text = action.text.trim()
    <span class="hljs-keyword">return</span> [ ...state, text ]
  }
})
</code></pre>
<p>We can write the following helper to accomplish this:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createReducer</span>(<span class="hljs-params">initialState, handlers</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reducer</span>(<span class="hljs-params">state = initialState, action</span>) </span>{
    <span class="hljs-keyword">if</span> (handlers.hasOwnProperty(action.type)) {
      <span class="hljs-keyword">return</span> handlers[action.type](state, action)
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">return</span> state
    }
  }
}
</code></pre>
<p>This wasn&apos;t difficult, was it? Redux doesn&apos;t provide such a helper function by default because there are many ways to write it. Maybe you want it to automatically convert plain JS objects to Immutable objects to hydrate the server <a href="../Glossary.html#state" class="glossary-term" title="">state</a>. Maybe you want to merge the returned <a href="../Glossary.html#state" class="glossary-term" title="">state</a> with the current <a href="../Glossary.html#state" class="glossary-term" title="">state</a>. There may be different approaches to a &#x201C;catch all&#x201D; handler. All of this depends on the conventions you choose for your team on a specific project.</p>
<p>The Redux <a href="../Glossary.html#reducer" class="glossary-term" title="">reducer</a> API is <code>(state, action) =&gt; state</code>, but how you create those reducers is up to you.</p>

                                
                                </section>
                            
    </div>
    <div class="search-results">
        <div class="has-results">
            
            <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
            <ul class="search-results-list"></ul>
            
        </div>
        <div class="no-results">
            
            <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
            
        </div>
    </div>
</div>

                        </div>
                    </div>
                
            </div>

            
                
                <a href="UsingObjectSpreadOperator.html" class="navigation navigation-prev " aria-label="Previous page: Using Object Spread Operator">
                    <i class="fa fa-angle-left"></i>
                </a>
                
                
                <a href="ServerRendering.html" class="navigation navigation-next " aria-label="Next page: Server Rendering">
                    <i class="fa fa-angle-right"></i>
                </a>
                
            
        
    </div>

    <script>
        var gitbook = gitbook || [];
        gitbook.push(function() {
            gitbook.page.hasChanged({"page":{"title":"Reducing Boilerplate","level":"1.5.3","depth":2,"next":{"title":"Server Rendering","level":"1.5.4","depth":2,"path":"recipes/ServerRendering.md","ref":"./recipes/ServerRendering.md","articles":[]},"previous":{"title":"Using Object Spread Operator","level":"1.5.2","depth":2,"path":"recipes/UsingObjectSpreadOperator.md","ref":"./recipes/UsingObjectSpreadOperator.md","articles":[]},"dir":"ltr"},"config":{"gitbook":"*","theme":"default","variables":{},"plugins":["livereload"],"pluginsConfig":{"livereload":{},"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"}},"file":{"path":"recipes/ReducingBoilerplate.md","mtime":"2017-03-13T14:28:11.351Z","type":"markdown"},"gitbook":{"version":"3.2.2","time":"2017-03-15T14:47:19.389Z"},"basePath":"..","book":{"language":""}});
        });
    </script>
</div>

        
    <script src="../gitbook/gitbook.js"></script>
    <script src="../gitbook/theme.js"></script>
    
        
        <script src="../gitbook/gitbook-plugin-livereload/plugin.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search/search-engine.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search/search.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-sharing/buttons.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
        
    

    </body>
</html>

